package com.tszs.redis;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

/**
 * @类名：RedisUtils
 * @类描述：链接redis
 * @author 王俊
 */
public class RedisUtils {
	/**
	 * @类名：redisuitls
	 * @类描述：链接redis
	 * @author 王俊
	 * @param i
	 */
	private static JedisPool POOLS;
	private static String HOST = "127.0.0.1";
	private static int PORT = 6379;
	private static int TIMEOUT = 10000;
	private static String PASSWORD = "123456";
	private static JedisPool jedisPool = null;

	static {
		// 使用连接池
		// 【2】创建JedisPool所需的连接池配置
		JedisPoolConfig poolConfig = new JedisPoolConfig();
		// 最大连接数，默认8
		poolConfig.setMaxTotal(1024);
		// 最大空闲数,默认8
		poolConfig.setMaxIdle(200);
		// 最小空闲连接数，默认0
		poolConfig.setMinIdle(0);
		// 对象最小空闲时间，默认1800000毫秒(30分钟)
		poolConfig.setMinEvictableIdleTimeMillis(1800000);
		// 获取连接的最大等待毫秒数。如果设为小于0，则永远等待
		poolConfig.setMaxWaitMillis(-1);
		// 在创建对象时检测对象是否有效，true是，默认值是false
		poolConfig.setTestOnCreate(true);
		// 从对象池获取对象时检测对象是否有效，默认false
		poolConfig.setTestOnBorrow(true);
		// 在向对象池中归还对象时是否检测对象有效，true是，默认值是false
		poolConfig.setTestOnReturn(false);
		// 在检测空闲对象线程检测到对象不需要移除时，是否检测对象的有效性。true是，默认值是false
		poolConfig.setTestWhileIdle(false);
		// 检测空闲对象线程每次检测的空闲对象的数量。默认值是3；如果这个值小于0,则每次检测的空闲对象数量等于当前空闲对象数量除以这个值的绝对值，并对结果向上取整
		poolConfig.setNumTestsPerEvictionRun(3);
		// 是否启用后进先出, 默认true
		poolConfig.setLifo(true);
		// 多长时候执行一次空闲对象检测。单位是毫秒数。如果小于等于0，则不执行检测线程。默认值是-1
		poolConfig.setTimeBetweenEvictionRunsMillis(-1);
		// 当对象池没有空闲对象时，新的获取对象的请求是否阻塞。true阻塞。默认值是true;
		poolConfig.setBlockWhenExhausted(true);
		// 是否启用pool的jmx管理功能, 默认true
		poolConfig.setJmxEnabled(true);
		// 【1】创建JedisPool连接池
		jedisPool = new JedisPool(poolConfig, HOST, PORT, TIMEOUT, PASSWORD);
	}

	/**
	 * 同步获取Jedis
	 *
	 * @return
	 */
	public synchronized static Jedis getJedis() {
		if (jedisPool != null) {
			// 获取Jedis对象
			Jedis jedis = jedisPool.getResource();
			return jedis;
		}
		return null;
	}

	/**
	 * @释放jedis资源
	 */
	@SuppressWarnings("deprecation")
	public static void releaseResource(Jedis jedis) {
		if (jedis != null) {
			jedisPool.returnResource(jedis);
		}
	}

	/**
	 * @redis操作字符串
	 */
	public static void RString(String Rkey, String RValue) {
		Jedis jedis = RedisUtils.getJedis();
		jedis.select(0);// 库名
		// 添加数据
		jedis.set(Rkey, RValue);
	}



	/**
	 * @redis操作List集合
	 */
	public static Boolean setArrayList(String key, List<Object> list, Integer activeTime) {
		if (list != null && key != null && key != "") {
			Jedis jedis = POOLS.getResource();
			jedis.select(1);// 库名
			jedis.set(key, JSONArray.fromObject(list).toString());
			if (activeTime != null && activeTime > 0) {
				jedis.expire(key, activeTime);
			}
			jedis.close();
			return true;
		}
		return false;
	}

	/**
	 * @此方法将会把存在redis中的数据取出来，并封装成相应的Arraylist集合
	 * @param key  存储的名字
	 * @param beanClass  要封装成为的javaBean
	 * @return List
	 */
	public static List<Object> getArraylist(String key, Class<?> beanClass) {
		if (key != null && key != "" && beanClass != null) {
			Jedis jedis = POOLS.getResource();
			jedis.select(1);// 库名
			JSONArray jsonArray = JSONArray.fromObject(jedis.get(key));
			List<Object> list = new ArrayList<Object>();
			for (int i = 0; i < jsonArray.size(); i++) {
				Object object = JSONObject.toBean((JSONObject) jsonArray.get(i), beanClass);
				list.add(object);
			}
			return list;
		}
		return null;
	}

	/**
	 * @redis操作map集合
	 */
	public static boolean setMap(String key, Map<String, Object> map) {
		if (map != null && key != null && key != "") {
			Jedis jedis = POOLS.getResource();
			jedis.select(2);// 库名
			jedis.set(key, JSONObject.fromObject(map).toString());
			jedis.close();
			return true;
		}
		return false;
	}

	/**
	 * @此方法将会把存在redis中的数据取出来，并封装成相应的Map集合 
	 * @param key 存储的名字 *
	 * @param beanClass 要封装成的对象 
	 * @return 返回封装后的map集合
	 */
	public static Map<String, Object> getMap(String key, Class<?> beanClass) {
		if (key != null && key != "" && beanClass != null) {
			Jedis jedis = POOLS.getResource();
			jedis.select(2);// 库名
			Map<?, ?> map1 = (Map<?, ?>) JSONObject.fromObject(jedis.get(key));
			Set<?> set = map1.keySet();
			Iterator<?> ite = set.iterator();
			Map<String, Object> maps = new HashMap<String, Object>();
			while (ite.hasNext()) {
				String key1 = (String) ite.next();
				JSONObject jsonObject = JSONObject.fromObject(map1.get(key1));
				Object object = JSONObject.toBean(jsonObject, beanClass);
				maps.put(key1, object);
			}
			return maps;
		}
		return null;
	}

	/**
	 * @redis操作set集合
	 * 
	 */
	public static void RSet(String Rkey, String RValue) {
		Jedis jedis = RedisUtils.getJedis();
		jedis.select(3);// 库名1
		jedis.sadd(Rkey, RValue);
		System.out.println(jedis.smembers(Rkey));// 获取所有加入的value
	}
}
